package model.effect;

import model.entity.BasicEntity;
import model.map.GameMap;
import model.map.Location;
import model.map.World;
import utilities.*;

/**
 * This class represents an effect that will move an entity to a predefined location
 */
public class TeleportEffect extends Effect implements Archiveable {
	
	private String mapName;
	private Location loc;
	private World w = World.getInstance();
	
	/* --------------------------------------------------------------------------------
	 * Constructors
	   -------------------------------------------------------------------------------- */

	/**
	 * @param name
	 * @param mapName
	 * @param loc
	 */
	public TeleportEffect(String name, String mapName, Location loc) {
		super(name);
		this.mapName = mapName;
		this.loc = loc;
	}

	/**
	 * @param name
	 * @param loc
	 */
	public TeleportEffect(String name, Location loc) {
		super(name);
		this.mapName = null;
		this.loc = loc;
	}

	public TeleportEffect() {}

	/* --------------------------------------------------------------------------------
	 * Class methods
	   -------------------------------------------------------------------------------- */
	
	@Override
	public void doEffect(BasicEntity ent) {
		//TODO: Handle the ability to map switch
		if( shouldTeleportToAnotherMap(ent) ){
			GameMap gm = w.getCurrentMap();
			gm.removeEntity(ent);
			w.setCurrentMap(mapName);
			gm.addEntity(ent);
		}
		else{
			ent.setLocation(loc);
		}
	}

	@Override
	public String toString()
	{
		return super.toString() + "TeleportEffect [mapName=" + mapName + ", loc=" + loc + "]";
	}
	
	/* --------------------------------------------------------------------------------
	 * Getters and Setters
	   -------------------------------------------------------------------------------- */

	public void setMap(String mapName){
		this.mapName = mapName;
	}
	
	private boolean shouldTeleportToAnotherMap(BasicEntity e){
		if( mapName != null && e == w.getPlayer())
			return true;
		return false;
	}

	public Archive save() {
		Archive archive = super.save();
		
//		archive.putAttribute("mapName", this.mapName);
//		
//		archive.putClassName("loc", this.loc.getClass().getName());
//		archive.putOneRelationship("loc", this.loc);
		
		return archive;
	}
	
	public void load(Archive archive) {
		super.load(archive);
		
//		this.mapName = archive.getAttribute("mapName");
//		
//		this.loc = (Location)ModelFactory.getInstance().createInstanceWithClassName(archive.getClassName("loc"));
//		this.loc.load(archive.getOneRelationship("loc"));
	}
	
}
